import { AppDataSource } from '../config/database';
import { PaymentRecord, PaymentStatus } from '../entities/PaymentRecord';
import { User, PaymentStatus as UserPaymentStatus } from '../entities/User';
import { createWxPaySDK } from '../sdk/weixin/WxPaySDK';
import { wxPayConfig } from '../config';
import { Between } from 'typeorm';
import { PaymentProofGenerator } from '../utils/paymentProofGenerator';

/**
 * 支付状态同步服务
 * 定期查询待支付和退款中的订单，并通过微信支付接口更新订单状态
 */
export class PaymentStatusService {
  private wxPaySDK;
  private intervalId: NodeJS.Timeout | null = null;
  private isRunning = false;
  private readonly INTERVAL_TIME = 2 * 60 * 1000; // 2分钟
  private readonly MAX_QUERY_DAYS = 14; // 最多查询14天内的订单

  constructor() {
    // 检查微信支付配置
    if (!wxPayConfig.appId || !wxPayConfig.mchId || !wxPayConfig.mchKey) {
      console.error('微信支付配置不完整，无法初始化支付状态同步服务', {
        appId: wxPayConfig.appId ? '已设置' : '未设置',
        mchId: wxPayConfig.mchId ? '已设置' : '未设置',
        mchKey: wxPayConfig.mchKey ? '已设置' : '未设置',
        notifyUrl: wxPayConfig.notifyUrl ? '已设置' : '未设置'
      });
    } else {
      console.log('微信支付配置检查通过，初始化支付状态同步服务');
    }

    // 初始化微信支付SDK
    this.wxPaySDK = createWxPaySDK({
      appId: wxPayConfig.appId,
      appSecret: wxPayConfig.appSecret,
      mchId: wxPayConfig.mchId,
      mchKey: wxPayConfig.mchKey,
      notifyUrl: wxPayConfig.notifyUrl
    });
  }

  /**
   * 启动服务
   */
  public start(): void {
    if (this.intervalId) {
      console.log('支付状态同步服务已经在运行中');
      return;
    }

    console.log('启动支付状态同步服务，间隔时间：2分钟');
    this.intervalId = setInterval(() => this.syncPaymentStatus(), this.INTERVAL_TIME);
    
    // 立即执行一次
    this.syncPaymentStatus();
  }

  /**
   * 停止服务
   */
  public stop(): void {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
      console.log('支付状态同步服务已停止');
    }
  }

  /**
   * 同步支付状态
   */
  private async syncPaymentStatus(): Promise<void> {
    // 防止并发执行
    if (this.isRunning) {
      console.log('上一次支付状态同步任务尚未完成，跳过本次执行');
      return;
    }

    this.isRunning = true;
    console.log('开始执行支付状态同步任务', new Date().toISOString());

    try {
      // 查询待支付的订单
      await this.syncPendingOrders();
      
      // 查询退款中的订单
      await this.syncRefundingOrders();
      
      console.log('支付状态同步任务完成', new Date().toISOString());
    } catch (error) {
      console.error('支付状态同步任务执行失败:', error);
    } finally {
      this.isRunning = false;
    }
  }

  /**
   * 同步待支付的订单
   */
  private async syncPendingOrders(): Promise<void> {
    try {
      // 计算查询时间范围，只查询最近14天内的订单
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - this.MAX_QUERY_DAYS);

      // 查询待支付状态的订单
      const pendingOrders = await AppDataSource.getRepository(PaymentRecord).find({
        where: {
          status: PaymentStatus.PENDING,
          createTime: Between(startDate, endDate)
        },
        order: {
          createTime: 'DESC'
        },
        take: 100 // 每次最多处理100条记录
      });

      console.log(`找到 ${pendingOrders.length} 条待支付订单`);

      // 逐个查询订单状态
      for (const order of pendingOrders) {
        try {
          await this.processOrder(order);
          // 添加延迟，避免请求过于频繁
          await new Promise(resolve => setTimeout(resolve, 500));
        } catch (error) {
          console.error(`处理订单 ${order.orderNo} 时发生异常，跳过该订单:`, error);
          continue;
        }
      }
    } catch (error) {
      console.error('同步待支付订单失败:', error);
    }
  }

  /**
   * 同步退款中的订单
   */
  private async syncRefundingOrders(): Promise<void> {
    try {
      // 计算查询时间范围，只查询最近14天内的订单
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - this.MAX_QUERY_DAYS);

      // 查询退款中状态的订单
      const refundingOrders = await AppDataSource.getRepository(PaymentRecord).find({
        where: {
          status: PaymentStatus.REFUNDING,
          updateTime: Between(startDate, endDate)
        },
        order: {
          updateTime: 'DESC'
        },
        take: 100 // 每次最多处理100条记录
      });

      console.log(`找到 ${refundingOrders.length} 条退款中订单`);

      // TODO: 实现退款查询逻辑
      // 由于当前系统可能没有退款接口，这部分逻辑暂时留空
      // 如果需要实现，可以参考订单查询的方式，调用微信支付的退款查询接口
    } catch (error) {
      console.error('同步退款中订单失败:', error);
    }
  }

  /**
   * 处理单个订单
   * @param order 订单记录
   */
  private async processOrder(order: PaymentRecord): Promise<void> {
    try {
      console.log(`处理订单 ${order.orderNo}, 当前状态: ${order.status}`);

      // 调用微信支付查询订单接口
      console.log(`开始查询订单状态: ${order.orderNo}`);
      const result = await this.wxPaySDK.queryOrder(order.orderNo);
      console.log(`订单 ${order.orderNo} 查询返回结果:`, JSON.stringify(result));

      if (!result) {
        console.error(`订单 ${order.orderNo} 查询返回空结果`);
        return;
      }

      if (!result.success) {
        console.error(`查询订单 ${order.orderNo} 失败:`, {
          errorCode: result.errorCode || '未知错误码',
          errorMessage: result.errorMessage || '未知错误',
          result: JSON.stringify(result)
        });
        return;
      }

      if (!result.data) {
        console.error(`订单 ${order.orderNo} 查询成功但数据为空`);
        return;
      }

      console.log(`订单 ${order.orderNo} 查询结果:`, {
        tradeState: result.data.tradeState,
        tradeStateDesc: result.data.tradeStateDesc,
        transactionId: result.data.transactionId || '无交易ID',
        timeEnd: result.data.timeEnd || '无支付时间'
      });

      // 根据查询结果更新订单状态
      if (result.data.tradeState === 'SUCCESS') {
        // 支付成功
        // 处理微信支付时间格式，格式为yyyyMMddHHmmss，需要转换为标准日期格式
        let paymentTime: Date;
        try {
          if (result.data.timeEnd) {
            // 确保 timeEnd 是字符串类型
            const timeEndStr = result.data.timeEnd.toString();
            console.log(`原始支付时间字符串: ${timeEndStr}, 长度: ${timeEndStr.length}, 类型: ${typeof result.data.timeEnd}`);
            
            if (timeEndStr.length === 14) {
              const year = timeEndStr.substring(0, 4);
              const month = timeEndStr.substring(4, 6);
              const day = timeEndStr.substring(6, 8);
              const hour = timeEndStr.substring(8, 10);
              const minute = timeEndStr.substring(10, 12);
              const second = timeEndStr.substring(12, 14);
              
              const dateStr = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
              console.log(`解析支付时间: ${timeEndStr} -> ${dateStr}`);
              
              paymentTime = new Date(dateStr);
              
              // 验证日期是否有效
              if (isNaN(paymentTime.getTime())) {
                throw new Error(`无效的日期: ${dateStr}`);
              }
              
              console.log(`支付时间解析成功: ${paymentTime.toISOString()}`);
            } else {
              throw new Error(`无效的时间格式长度: ${timeEndStr}`);
            }
          } else {
            throw new Error(`无效的时间格式: 时间为空`);
          }
        } catch (error: any) {
          console.error(`解析支付时间失败: ${result.data.timeEnd}`, error);
          paymentTime = new Date(); // 使用当前时间作为备选
          console.log(`使用当前时间作为支付时间: ${paymentTime.toISOString()}`);
        }
        
        // 创建查询运行器以支持事务
        const queryRunner = AppDataSource.createQueryRunner();
        
        // 开始事务
        await queryRunner.connect();
        await queryRunner.startTransaction();
        
        try {
          // 更新支付记录状态
          order.status = PaymentStatus.PAID;
          order.paymentTime = paymentTime;
          order.transactionId = result.data.transactionId;
          order.updatedBy = 'system';
          
          console.log(`更新订单 ${order.orderNo} 状态为已支付，支付时间: ${paymentTime.toISOString()}`);
          
          // 检查是否已有支付凭证，如果没有则生成
          if (!order.paymentProof) {
            try {
              const paymentProofPath = await this.generatePaymentProof(order);
              order.paymentProof = paymentProofPath;
              console.log(`生成支付凭证成功: ${paymentProofPath}`);
            } catch (error: any) {
              console.error(`生成支付凭证失败: ${error.message}`);
              // 即使生成凭证失败，也继续处理支付流程
            }
          }
          
          // 在事务中保存支付记录
          await queryRunner.manager.save(order);
          console.log(`订单 ${order.orderNo} 已更新为已支付状态`);
          
          // 在事务中更新用户缴费状态
          const user = await queryRunner.manager.findOne(User, {
            where: { id: order.userId }
          });
          
          if (user) {
            // 更新用户缴费状态
            user.paymentStatus = UserPaymentStatus.PAID; // 已缴费
            user.updatedBy = 'system';
            
            await queryRunner.manager.save(user);
            console.log(`用户 ${order.userId} 的缴费状态已更新为已缴费`);
          } else {
            console.error(`用户不存在: ${order.userId}`);
          }
          
          // 提交事务
          await queryRunner.commitTransaction();
          console.log(`订单 ${order.orderNo} 处理完成，事务已提交`);
        } catch (txError: any) {
          // 发生错误时回滚事务
          await queryRunner.rollbackTransaction();
          console.error(`处理订单 ${order.orderNo} 时事务出错，已回滚:`, txError);
        } finally {
          // 释放查询运行器
          await queryRunner.release();
        }
      } else if (result.data.tradeState === 'CLOSED' || result.data.tradeState === 'REVOKED' || result.data.tradeState === 'PAYERROR') {
        // 订单关闭、撤销或支付失败
        // 创建查询运行器以支持事务
        const queryRunner = AppDataSource.createQueryRunner();
        
        // 开始事务
        await queryRunner.connect();
        await queryRunner.startTransaction();
        
        try {
          // 更新支付记录状态
          order.status = PaymentStatus.FAILED;
          order.updatedBy = 'system';
          
          // 在事务中保存支付记录
          await queryRunner.manager.save(order);
          console.log(`订单 ${order.orderNo} 已更新为失败状态: ${result.data.tradeState}`);
          
          // 提交事务
          await queryRunner.commitTransaction();
        } catch (txError: any) {
          // 发生错误时回滚事务
          await queryRunner.rollbackTransaction();
          console.error(`处理订单 ${order.orderNo} 失败状态更新时事务出错，已回滚:`, txError);
        } finally {
          // 释放查询运行器
          await queryRunner.release();
        }
      } else if (result.data.tradeState === 'NOTPAY' || result.data.tradeState === 'USERPAYING') {
        // 未支付或用户支付中，不做处理
        console.log(`订单 ${order.orderNo} 仍在待支付状态: ${result.data.tradeState}`);
      } else {
        // 其他状态，记录日志
        console.log(`订单 ${order.orderNo} 处于未处理的状态: ${result.data.tradeState}`);
      }
    } catch (error: any) {
      console.error(`处理订单 ${order.orderNo} 时出错:`, {
        message: error.message,
        stack: error.stack,
        orderNo: order.orderNo,
        userId: order.userId,
        status: order.status
      });
    }
  }

  /**
   * 生成支付凭证
   * @param paymentRecord 支付记录
   * @returns 支付凭证路径
   */
  private async generatePaymentProof(paymentRecord: PaymentRecord): Promise<string> {
    try {
      // 获取用户信息
      const user = await AppDataSource.getRepository(User).findOne({
        where: { id: paymentRecord.userId }
      });
      
      // 使用统一的支付凭证生成器
      return await PaymentProofGenerator.generatePaymentProof(paymentRecord, user || undefined);
    } catch (error: any) {
      console.error('生成支付凭证失败:', error);
      throw error;
    }
  }

  /**
   * 更新用户缴费状态
   * @param userId 用户ID
   */
  private async updateUserPaymentStatus(userId: string): Promise<void> {
    // 创建查询运行器以支持事务
    const queryRunner = AppDataSource.createQueryRunner();
    
    // 开始事务
    await queryRunner.connect();
    await queryRunner.startTransaction();
    
    try {
      const user = await queryRunner.manager.findOne(User, {
        where: { id: userId }
      });

      if (!user) {
        console.error('用户不存在:', userId);
        await queryRunner.rollbackTransaction();
        return;
      }

      // 更新用户缴费状态
      user.paymentStatus = UserPaymentStatus.PAID; // 已缴费
      user.updatedBy = 'system';
      
      await queryRunner.manager.save(user);
      console.log(`用户 ${userId} 的缴费状态已更新为已缴费`);
      
      // 提交事务
      await queryRunner.commitTransaction();
    } catch (error) {
      // 发生错误时回滚事务
      await queryRunner.rollbackTransaction();
      console.error('更新用户缴费状态失败:', error);
    } finally {
      // 释放查询运行器
      await queryRunner.release();
    }
  }
}

// 导出单例实例
export const paymentStatusService = new PaymentStatusService(); 